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