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.convert;
017
018import javax.money.CurrencyUnit;
019import javax.money.NumberValue;
020import javax.money.convert.ConversionContext;
021import javax.money.convert.ExchangeRate;
022import javax.money.convert.RateType;
023
024import java.util.ArrayList;
025import java.util.Arrays;
026import java.util.List;
027import java.util.Objects;
028
029/**
030 * Builder for creating new instances of {@link javax.money.convert.ExchangeRate}. Note that
031 * instances of this class are not thread-safe.
032 *
033 * @author Anatole Tresch
034 * @author Werner Keil
035 */
036public class ExchangeRateBuilder {
037
038    /**
039     * The {@link javax.money.convert.ConversionContext}.
040     */
041    ConversionContext conversionContext;
042    /**
043     * The base (source) currency.
044     */
045    CurrencyUnit base;
046    /**
047     * The term (target) currency.
048     */
049    CurrencyUnit term;
050    /**
051     * The conversion factor.
052     */
053    NumberValue factor;
054    /**
055     * The chain of invovled rates.
056     */
057    List<ExchangeRate> rateChain = new ArrayList<>();
058
059    /**
060     * Sets the exchange rate type
061     *
062     * @param rateType the {@link javax.money.convert.RateType} contained
063     */
064    public ExchangeRateBuilder(String provider, RateType rateType) {
065        this(ConversionContext.of(provider, rateType));
066    }
067
068    /**
069     * Sets the exchange rate type
070     *
071     * @param context the {@link javax.money.convert.ConversionContext} to be applied
072     */
073    public ExchangeRateBuilder(ConversionContext context) {
074        setContext(context);
075    }
076
077    /**
078     * Sets the exchange rate type
079     *
080     * @param rate the {@link javax.money.convert.ExchangeRate} to be applied
081     */
082    public ExchangeRateBuilder(ExchangeRate rate) {
083        setContext(rate.getContext());
084        setFactor(rate.getFactor());
085        setTerm(rate.getCurrency());
086        setBase(rate.getBaseCurrency());
087        setRateChain(rate.getExchangeRateChain());
088    }
089
090    /**
091     * Sets the base {@link javax.money.CurrencyUnit}
092     *
093     * @param base to base (source) {@link javax.money.CurrencyUnit} to be applied
094     * @return the builder instance
095     */
096    public ExchangeRateBuilder setBase(CurrencyUnit base) {
097        this.base = base;
098        return this;
099    }
100
101    /**
102     * Sets the terminating (target) {@link javax.money.CurrencyUnit}
103     *
104     * @param term to terminating {@link javax.money.CurrencyUnit} to be applied
105     * @return the builder instance
106     */
107    public ExchangeRateBuilder setTerm(CurrencyUnit term) {
108        this.term = term;
109        return this;
110    }
111
112    /**
113     * Sets the {@link javax.money.convert.ExchangeRate} chain.
114     *
115     * @param exchangeRates the {@link javax.money.convert.ExchangeRate} chain to be applied
116     * @return the builder instance
117     */
118    public ExchangeRateBuilder setRateChain(ExchangeRate... exchangeRates) {
119        this.rateChain.clear();
120        if (exchangeRates!=null) {
121            this.rateChain.addAll(Arrays.asList(exchangeRates.clone()));
122        }
123        return this;
124    }
125
126    /**
127     * Sets the {@link javax.money.convert.ExchangeRate} chain.
128     *
129     * @param exchangeRates the {@link javax.money.convert.ExchangeRate} chain to be applied
130     * @return the builder instance
131     */
132    public ExchangeRateBuilder setRateChain(List<ExchangeRate> exchangeRates) {
133        this.rateChain.clear();
134        if (exchangeRates!=null) {
135            this.rateChain.addAll(exchangeRates);
136        }
137        return this;
138    }
139
140
141    /**
142     * Sets the conversion factor, as the factor
143     * {@code base * factor = target}.
144     *
145     * @param factor the factor.
146     * @return The builder instance.
147     */
148    public ExchangeRateBuilder setFactor(NumberValue factor) {
149        this.factor = factor;
150        return this;
151    }
152
153    /**
154     * Sets the provider to be applied.
155     *
156     * @param conversionContext the {@link javax.money.convert.ConversionContext}, not null.
157     * @return The builder.
158     */
159    public ExchangeRateBuilder setContext(ConversionContext conversionContext) {
160        Objects.requireNonNull(conversionContext);
161        this.conversionContext = conversionContext;
162        return this;
163    }
164
165    /**
166     * Builds a new instance of {@link javax.money.convert.ExchangeRate}.
167     *
168     * @return a new instance of {@link javax.money.convert.ExchangeRate}.
169     * @throws IllegalArgumentException if the rate could not be built.
170     */
171    public ExchangeRate build() {
172        return new DefaultExchangeRate(this);
173    }
174
175    /**
176     * Initialize the {@link ExchangeRateBuilder} with an {@link javax.money.convert.ExchangeRate}. This is
177     * useful for creating a new rate, reusing some properties from an
178     * existing one.
179     *
180     * @param rate the base rate
181     * @return the Builder, for chaining.
182     */
183    public ExchangeRateBuilder setRate(ExchangeRate rate) {
184        this.base = rate.getBaseCurrency();
185        this.term = rate.getCurrency();
186        this.conversionContext = rate.getContext();
187        this.factor = rate.getFactor();
188        this.rateChain = rate.getExchangeRateChain();
189        this.term = rate.getCurrency();
190        return this;
191    }
192
193    @Override
194    public String toString() {
195        String sb = "org.javamoney.moneta.ExchangeRateBuilder: " +
196                "[conversionContext" + conversionContext + ',' +
197                "base" + base + ',' +
198                "term" + term + ',' +
199                "factor" + factor + ',' +
200                "rateChain" + rateChain + ']';
201        return sb;
202    }
203}