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.internal;
017
018import java.util.*;
019import java.util.logging.Level;
020import java.util.logging.Logger;
021
022import javax.money.CurrencyQuery;
023import javax.money.CurrencyUnit;
024import javax.money.spi.CurrencyProviderSpi;
025
026/**
027 * Default implementation of a {@link CurrencyUnit} based on the using the JDK's
028 * {@link Currency}.
029 * 
030 * @version 0.5.1
031 * @author Anatole Tresch
032 * @author Werner Keil
033 */
034public class JDKCurrencyProvider implements CurrencyProviderSpi {
035
036        /** Internal shared cache of {@link javax.money.CurrencyUnit} instances. */
037        private static final Map<String, CurrencyUnit> CACHED = new HashMap<>();
038
039        public JDKCurrencyProvider() {
040                for (Currency jdkCurrency : Currency.getAvailableCurrencies()) {
041                        CurrencyUnit cu = new JDKCurrencyAdapter(jdkCurrency);
042                        CACHED.put(cu.getCurrencyCode(), cu);
043                }
044        }
045
046    @Override
047    public String getProviderName(){
048        return "default";
049    }
050
051    /**
052     * Return a {@link CurrencyUnit} instances matching the given
053     * {@link javax.money.CurrencyContext}.
054     *
055     * @param currencyQuery the {@link javax.money.CurrencyContext} containing the parameters determining the query. not null.
056     * @return the corresponding {@link CurrencyUnit}, or null, if no such unit
057     * is provided by this provider.
058     */
059    public Set<CurrencyUnit> getCurrencies(CurrencyQuery currencyQuery){
060        Set<CurrencyUnit> result = new HashSet<>();
061        if(!currencyQuery.getCurrencyCodes().isEmpty()) {
062            for (String code : currencyQuery.getCurrencyCodes()) {
063                CurrencyUnit cu = CACHED.get(code);
064                if (cu != null) {
065                    result.add(cu);
066                }
067            }
068            return result;
069        }
070        if(!currencyQuery.getCountries().isEmpty()) {
071            for (Locale country : currencyQuery.getCountries()) {
072                CurrencyUnit cu = getCurrencyUnit(country);
073                if (cu != null) {
074                    result.add(cu);
075                }
076            }
077            return result;
078        }
079        result.addAll(CACHED.values());
080        return result;
081    }
082
083    private CurrencyUnit getCurrencyUnit(Locale locale) {
084                Currency cur;
085                try {
086                        cur = Currency.getInstance(locale);
087                        if (Objects.nonNull(cur)) {
088                                return CACHED.get(cur.getCurrencyCode());
089                        }
090                } catch (Exception e) {
091                        if (Logger.getLogger(getClass().getName()).isLoggable(Level.FINEST)) {
092                                Logger.getLogger(getClass().getName()).finest(
093                                                "No currency for locale found: " + locale);
094                        }
095                }
096                return null;
097        }
098
099}