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