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 org.javamoney.moneta.spi.base.BaseCurrencyProviderSpi; 019 020import javax.money.CurrencyQuery; 021import javax.money.CurrencyUnit; 022import java.util.*; 023import java.util.concurrent.ConcurrentHashMap; 024 025/** 026 * This class provides a programmatic singleton for globally registering new {@link java.util.Currency} into the 027 * {@link javax.money.Monetary} singleton either by currency code, locale, or both. 028 */ 029public class ConfigurableCurrencyUnitProvider extends BaseCurrencyProviderSpi { 030 /** 031 * The currency units, identified by currency code. 032 */ 033 private static final Map<String, CurrencyUnit> currencyUnits = new ConcurrentHashMap<>(); 034 /** 035 * The currency units, identified by numeric code. 036 */ 037 private static final Map<Integer, CurrencyUnit> currencyUnitsByNumericCode = new ConcurrentHashMap<>(); 038 /** 039 * The currency units identified by Locale. 040 */ 041 private static final Map<Locale, CurrencyUnit> currencyUnitsByLocale = new ConcurrentHashMap<>(); 042 043 044 /** 045 * Return a {@link CurrencyUnit} instances matching the given 046 * {@link javax.money.CurrencyContext}. 047 * 048 * @param currencyQuery the {@link javax.money.CurrencyQuery} containing the parameters determining the query. not null. 049 * @return the corresponding {@link CurrencyUnit}, or null, if no such unit 050 * is provided by this provider. 051 */ 052 public Set<CurrencyUnit> getCurrencies(CurrencyQuery currencyQuery) { 053 Set<CurrencyUnit> result = new HashSet<>(currencyUnits.size()); 054 if (!currencyQuery.getCurrencyCodes().isEmpty()) { 055 for (String code : currencyQuery.getCurrencyCodes()) { 056 CurrencyUnit cu = currencyUnits.get(code); 057 if (cu != null) { 058 result.add(cu); 059 } 060 } 061 return result; 062 } 063 if (!currencyQuery.getCountries().isEmpty()) { 064 for (Locale locale : currencyQuery.getCountries()) { 065 CurrencyUnit cu = currencyUnitsByLocale.get(locale); 066 if (cu != null) { 067 result.add(cu); 068 } 069 } 070 return result; 071 } 072 if (!currencyQuery.getNumericCodes().isEmpty()) { 073 for (Integer numericCode : currencyQuery.getNumericCodes()) { 074 CurrencyUnit cu = currencyUnitsByNumericCode.get(numericCode); 075 if (cu != null) { 076 result.add(cu); 077 } 078 } 079 return result; 080 } 081 result.addAll(currencyUnits.values()); 082 return result; 083 } 084 085 /** 086 * Registers a new currency unit under its currency code and potentially numeric code. 087 * 088 * @param currencyUnit the new currency to be registered, not null. 089 * @return any unit instance registered previously by this instance, or null. 090 */ 091 public static CurrencyUnit registerCurrencyUnit(CurrencyUnit currencyUnit) { 092 Objects.requireNonNull(currencyUnit); 093 CurrencyUnit registered = ConfigurableCurrencyUnitProvider.currencyUnits.put(currencyUnit.getCurrencyCode(), currencyUnit); 094 int numericCode = currencyUnit.getNumericCode(); 095 if (numericCode != -1) { 096 ConfigurableCurrencyUnitProvider.currencyUnitsByNumericCode.put(numericCode, currencyUnit); 097 } 098 return registered; 099 } 100 101 /** 102 * Registers a new currency unit under the given Locale. 103 * 104 * @param currencyUnit the new currency to be registered, not null. 105 * @param locale the Locale, not null. 106 * @return any unit instance registered previously by this instance, or null. 107 */ 108 public static CurrencyUnit registerCurrencyUnit(CurrencyUnit currencyUnit, Locale locale) { 109 Objects.requireNonNull(locale); 110 Objects.requireNonNull(currencyUnit); 111 return ConfigurableCurrencyUnitProvider.currencyUnitsByLocale.put(locale, currencyUnit); 112 } 113 114 /** 115 * Removes a CurrencyUnit. 116 * 117 * @param currencyCode the currency code, not null. 118 * @return any unit instance removed, or null. 119 */ 120 public static CurrencyUnit removeCurrencyUnit(String currencyCode) { 121 Objects.requireNonNull(currencyCode); 122 CurrencyUnit removed = ConfigurableCurrencyUnitProvider.currencyUnits.remove(currencyCode); 123 if (removed != null) { 124 int numericCode = removed.getNumericCode(); 125 if (numericCode != -1) { 126 ConfigurableCurrencyUnitProvider.currencyUnitsByNumericCode.remove(numericCode); 127 } 128 } 129 return removed; 130 } 131 132 /** 133 * Removes a CurrencyUnit. 134 * 135 * @param locale the Locale, not null. 136 * @return any unit instance removed, or null. 137 */ 138 public static CurrencyUnit removeCurrencyUnit(Locale locale) { 139 Objects.requireNonNull(locale); 140 return ConfigurableCurrencyUnitProvider.currencyUnitsByLocale.remove(locale); 141 } 142 143 /* 144 * (non-Javadoc) 145 * 146 * @see java.lang.Object#toString() 147 */ 148 @Override 149 public String toString() { 150 return "ConfigurableCurrencyUnitProvider [currencyUnits=" + currencyUnits 151 + ", currencyUnitsByNumericCode=" + currencyUnitsByNumericCode 152 + ", currencyUnitsByLocale=" + currencyUnitsByLocale + ']'; 153 } 154 155}