001/**
002 * Copyright (c) 2012, 2015, 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;
017
018import org.javamoney.moneta.internal.ConfigurableCurrencyUnitProvider;
019
020import javax.money.CurrencyContextBuilder;
021import javax.money.CurrencyUnit;
022import javax.money.CurrencyContext;
023import java.util.Locale;
024import java.util.Objects;
025
026/**
027 * Builder for constructing new instances of {@link BuildableCurrencyUnit} using a fluent
028 * API.
029 */
030public final class CurrencyUnitBuilder {
031    /**
032     * The currency code.
033     */
034    String currencyCode;
035    /**
036     * The (optional) numeric code.
037     */
038    int numericCode = -1;
039    /**
040     * The default fraction digits.
041     */
042    int defaultFractionDigits = 2;
043    /**
044     * The currency's context.
045     */
046    CurrencyContext currencyContext;
047
048    /**
049     * Private constructor, use #of() methods.
050     */
051    private CurrencyUnitBuilder() {
052    }
053
054    /**
055     * Creates a new CurrencyUnitBuilder.
056     *
057     * @param currencyCode    the (unique) and identifying currency code, not null.
058     * @param currencyContext The currency context to be used.
059     */
060    public static CurrencyUnitBuilder of(String currencyCode, CurrencyContext currencyContext) {
061        return new CurrencyUnitBuilder(currencyCode, currencyContext);
062    }
063
064    /**
065     * Creates a new CurrencyUnitBuilder, creates a simple CurrencyContext using the given provider name.
066     *
067     * @param currencyCode the (unique) and identifying currency code, not null.
068     * @param providerName the currency provider, not null.
069     */
070    public static CurrencyUnitBuilder of(String currencyCode, String providerName) {
071        return new CurrencyUnitBuilder(currencyCode, CurrencyContextBuilder.of(providerName).build());
072    }
073
074    /**
075     * Creates a new Builder.
076     *
077     * @param currencyCode the (unique) and identifying currency code, not null.
078     */
079    private CurrencyUnitBuilder(String currencyCode, CurrencyContext currencyContext) {
080        Objects.requireNonNull(currencyCode, "currencyCode required");
081        this.currencyCode = currencyCode;
082        Objects.requireNonNull(currencyContext, "currencyContext required");
083        this.currencyContext = currencyContext;
084    }
085
086    /**
087     * Allows to set the currency code, for creating multiple instances, using one Builder.
088     *
089     * @param currencyCode the (unique) and identifying currency code, not null.
090     * @return the Builder, for chaining.
091     * @see javax.money.CurrencyUnit#getCurrencyCode()
092     */
093    public CurrencyUnitBuilder setCurrencyCode(String currencyCode) {
094        Objects.requireNonNull(currencyCode, "currencyCode required");
095        this.currencyCode = currencyCode;
096        this.currencyContext = CurrencyContextBuilder.of(getClass().getSimpleName()).build();
097        return this;
098    }
099
100    /**
101     * Set the numeric code (optional).
102     *
103     * @param numericCode The numeric currency code, &gt;= -1. .1 hereby means <i>undefined</i>.
104     * @return the Builder, for chaining.
105     * @see javax.money.CurrencyUnit#getNumericCode()
106     */
107    public CurrencyUnitBuilder setNumericCode(int numericCode) {
108        if (numericCode < -1) {
109            throw new IllegalArgumentException("numericCode must be >= -1");
110        }
111        this.numericCode = numericCode;
112        return this;
113    }
114
115    /**
116     * Set the default fraction digits.
117     *
118     * @param defaultFractionDigits the default fraction digits, &gt;= 0.
119     * @return the Builder, for chaining.
120     * @see javax.money.CurrencyUnit#getDefaultFractionDigits()
121     */
122    public CurrencyUnitBuilder setDefaultFractionDigits(int defaultFractionDigits) {
123        if (defaultFractionDigits < 0) {
124            throw new IllegalArgumentException("defaultFractionDigits must be >= 0");
125        }
126        this.defaultFractionDigits = defaultFractionDigits;
127        return this;
128    }
129
130    /**
131     * Returns a new instance of {@link BuildableCurrencyUnit}.
132     *
133     * @return the new CurrencyUnit instance.
134     * @throws javax.money.MonetaryException if creation fails
135     */
136    public CurrencyUnit build() {
137        return build(false);
138    }
139
140    /**
141     * Returns a new instance of {@link BuildableCurrencyUnit} and publishes it so it is
142     * accessible from the {@code Monetary} singleton.
143     *
144     * @param register if {@code true} the instance created is published so it is accessible from
145     *                 the {@code Monetary} singleton.
146     * @return the new CurrencyUnit instance.
147     * @see javax.money.Monetary#getCurrency(String, String...)
148     */
149    public CurrencyUnit build(boolean register) {
150        BuildableCurrencyUnit cu = new BuildableCurrencyUnit(this);
151        if (register) {
152            ConfigurableCurrencyUnitProvider.registerCurrencyUnit(cu);
153        }
154        return cu;
155    }
156
157    /**
158     * Returns a new instance of {@link BuildableCurrencyUnit} and publishes it so it is
159     * accessible from the {@code Monetary} singleton.
160     *
161     * @param register if {@code true} the instance created is published so it is accessible from
162     *                 the {@code Monetary} singleton.
163     * @param locale   country Locale for making the currency for the given country.
164     * @return the new CurrencyUnit instance.
165     * @see javax.money.Monetary#getCurrency(String, String...)
166     * @see javax.money.Monetary#getCurrency(java.util.Locale, String...)
167     */
168    public CurrencyUnit build(boolean register, Locale locale) {
169        BuildableCurrencyUnit cu = new BuildableCurrencyUnit(this);
170        if (register) {
171            ConfigurableCurrencyUnitProvider.registerCurrencyUnit(cu);
172            ConfigurableCurrencyUnitProvider.registerCurrencyUnit(cu, locale);
173        }
174        return cu;
175    }
176}