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; 017 018import org.javamoney.moneta.internal.ConfigurableCurrencyUnitProvider; 019 020import javax.money.*; 021import javax.money.CurrencyContext; 022 023import java.util.Locale; 024import java.util.Objects; 025 026/** 027 * Implementation of {@link javax.money.CurrencyUnit} that allows to create new instances using a fluent API. 028 * Instances created also can be added to the {@link org.javamoney.moneta.internal.ConfigurableCurrencyUnitProvider} 029 * singleton, which publishes the instances, so they are visible from the {@link javax.money.MonetaryCurrencies} 030 * singleton. 031 */ 032public final class BuildableCurrencyUnit implements CurrencyUnit, Comparable<CurrencyUnit>{ 033 034 /** 035 * The unique currency code. 036 */ 037 private String currencyCode; 038 /** 039 * The (optional) numeric code. 040 */ 041 private int numericCode; 042 /** 043 * The default fraction digits. 044 */ 045 private int defaultFractionDigits; 046 /** 047 * THe currency's context. 048 */ 049 private javax.money.CurrencyContext currencyContext; 050 051 /** 052 * Constructor, called from the Builder. 053 * 054 * @param builder the builder, never null. 055 */ 056 private BuildableCurrencyUnit(Builder builder){ 057 Objects.requireNonNull(builder.currencyCode, "currencyCode required"); 058 if(builder.numericCode < -1){ 059 throw new MonetaryException("numericCode must be >= -1"); 060 } 061 if(builder.defaultFractionDigits < 0){ 062 throw new MonetaryException("defaultFractionDigits must be >= 0"); 063 } 064 if(builder.currencyContext == null){ 065 throw new MonetaryException("currencyContext must be != null"); 066 } 067 this.defaultFractionDigits = builder.defaultFractionDigits; 068 this.numericCode = builder.numericCode; 069 this.currencyCode = builder.currencyCode; 070 this.currencyContext = builder.currencyContext; 071 } 072 073 @Override 074 public String getCurrencyCode(){ 075 return currencyCode; 076 } 077 078 @Override 079 public int getNumericCode(){ 080 return numericCode; 081 } 082 083 @Override 084 public int getDefaultFractionDigits(){ 085 return defaultFractionDigits; 086 } 087 088 @Override 089 public CurrencyContext getCurrencyContext(){ 090 return currencyContext; 091 } 092 093 @Override 094 public int compareTo(CurrencyUnit o){ 095 Objects.requireNonNull(o); 096 return this.currencyCode.compareTo(o.getCurrencyCode()); 097 } 098 099 /* (non-Javadoc) 100 * @see java.lang.Object#hashCode() 101 */ 102 @Override 103 public int hashCode(){ 104 return Objects.hashCode(currencyCode); 105 } 106 107 /* (non-Javadoc) 108 * @see java.lang.Object#equals(java.lang.Object) 109 */ 110 @Override 111 public boolean equals(Object obj) { 112 if (obj == this) { 113 return true; 114 } 115 if (obj instanceof BuildableCurrencyUnit) { 116 BuildableCurrencyUnit other = (BuildableCurrencyUnit) obj; 117 return Objects.equals(currencyCode, other.currencyCode); 118 } 119 return false; 120 } 121 122 /* (non-Javadoc) 123 * @see java.lang.Object#toString() 124 */ 125 @Override 126 public String toString(){ 127 return "BuildableCurrencyUnit(currencyCode=" + currencyCode + ", numericCode=" + numericCode + 128 ", defaultFractionDigits=" + defaultFractionDigits + ", context="+this.currencyContext+")"; 129 } 130 131 132 /** 133 * Builder for constructing new instances o{@link org.javamoney.moneta.BuildableCurrencyUnit} using a fluent 134 * API. 135 */ 136 public static final class Builder{ 137 /** 138 * The currency code. 139 */ 140 private String currencyCode; 141 /** 142 * The (optional) numeric code. 143 */ 144 private int numericCode = -1; 145 /** 146 * The default fraction digits. 147 */ 148 private int defaultFractionDigits = 2; 149 /** 150 * THe currency's context. 151 */ 152 private javax.money.CurrencyContext currencyContext; 153 154 /** 155 * Creats a new Builder. 156 * 157 * @param currencyCode the (unique) and identifying currency code, not null. 158 */ 159 public Builder(String currencyCode, javax.money.CurrencyContext currencyContext){ 160 Objects.requireNonNull(currencyCode, "currencyCode required"); 161 this.currencyCode = currencyCode; 162 Objects.requireNonNull(currencyContext, "currencyContext required"); 163 this.currencyContext = currencyContext; 164 } 165 166 /** 167 * Allows to set the currency code, for creating multiple instances, using one Builder. 168 * 169 * @param currencyCode the (unique) and identifying currency code, not null. 170 * @return the Builder, for chaining. 171 * @see javax.money.CurrencyUnit#getCurrencyCode() 172 */ 173 public Builder setCurrencyCode(String currencyCode){ 174 Objects.requireNonNull(currencyCode, "currencyCode required"); 175 this.currencyCode = currencyCode; 176 this.currencyContext = CurrencyContextBuilder.create(getClass().getSimpleName()).build(); 177 return this; 178 } 179 180 /** 181 * Set the numeric code (optional). 182 * 183 * @param numericCode The numeric currency code, >= -1. .1 hereby means <i>undefined</i>. 184 * @return the Builder, for chaining. 185 * @see javax.money.CurrencyUnit#getNumericCode() 186 */ 187 public Builder setNumericCode(int numericCode){ 188 if(numericCode < -1){ 189 throw new IllegalArgumentException("numericCode must be >= -1"); 190 } 191 this.numericCode = numericCode; 192 return this; 193 } 194 195 /** 196 * Set the default fraction digits. 197 * 198 * @param defaultFractionDigits the default fraction digits, >= 0. 199 * @return the Builder, for chaining. 200 * @see javax.money.CurrencyUnit#getDefaultFractionDigits() 201 */ 202 public Builder setDefaultFractionDigits(int defaultFractionDigits){ 203 if(defaultFractionDigits < 0){ 204 throw new IllegalArgumentException("defaultFractionDigits must be >= 0"); 205 } 206 this.defaultFractionDigits = defaultFractionDigits; 207 return this; 208 } 209 210 /** 211 * Returns a new instance of {@link org.javamoney.moneta.BuildableCurrencyUnit}. 212 * 213 * @return the new CurrencyUnit instance. 214 * @throws MonetaryException if creation fails 215 */ 216 public BuildableCurrencyUnit build(){ 217 return build(false); 218 } 219 220 /** 221 * Returns a new instance of {@link org.javamoney.moneta.BuildableCurrencyUnit} and publishes it so it is 222 * accessible from the {@code MonetaryCurrencies} singleton. 223 * 224 * @param register if {@code true} the instance created is published so it is accessible from 225 * the {@code MonetaryCurrencies} singleton. 226 * @return the new CurrencyUnit instance. 227 * @see javax.money.MonetaryCurrencies#getCurrency(String, String...) 228 */ 229 public BuildableCurrencyUnit build(boolean register){ 230 BuildableCurrencyUnit cu = new BuildableCurrencyUnit(this); 231 if(register){ 232 ConfigurableCurrencyUnitProvider.registerCurrencyUnit(cu); 233 } 234 return cu; 235 } 236 237 /** 238 * Returns a new instance of {@link org.javamoney.moneta.BuildableCurrencyUnit} and publishes it so it is 239 * accessible from the {@code MonetaryCurrencies} singleton. 240 * 241 * @param register if {@code true} the instance created is published so it is accessible from 242 * the {@code MonetaryCurrencies} singleton. 243 * @param locale country Locale for making the currency for the given country. 244 * @return the new CurrencyUnit instance. 245 * @see javax.money.MonetaryCurrencies#getCurrency(String, String...) 246 * @see javax.money.MonetaryCurrencies#getCurrency(Locale, String...) 247 */ 248 public BuildableCurrencyUnit build(boolean register, Locale locale){ 249 BuildableCurrencyUnit cu = new BuildableCurrencyUnit(this); 250 if(register){ 251 ConfigurableCurrencyUnitProvider.registerCurrencyUnit(cu); 252 ConfigurableCurrencyUnitProvider.registerCurrencyUnit(cu, locale); 253 } 254 return cu; 255 } 256 } 257 258}